//final关键字
//final关键字用于限制某个类不能被继承，或者某个虚函数不能被重写
//final关键字放在类名或者虚函数名的后面即可






//类型转换
//to_string()函数     头文件<string>
//用于将各种数值类型转换为string类型字符串
int a = 11;
string str = to_string(a);  //str = "11"


//string类型->其他类型       //所有函数均在<string>头文件中
//int           stoi(const string&str, size_*t pos=nullptr, int base=10)      
string str1 = "123";        //若参数不为数字 则会报错
string str2 = "12.1";
string str3 = "aa";
int a = stoi(str1);     //a=123 
int b = stoi(str2);     //a=12
int c = stoi(str3);     //报错
//参数说明：str为需要转换的string字符串。pos是传出参数，存放哪个字符开始无法继续解析的位置，例如，123a45，传出的位置会为3
//base为进制，若为0则会自动检测数值进制（根据前缀0-八进制，0X-16进制）

//long          stol()
//longlong      stoll()
//unsigned long     stoul()
//unsigned long long    stoull()
//float         stof()
//double        stob()
//long double   stold()






//constexpt关键字
//const关键字有双重语义: 只读变量和修饰常量
void func(const int len1)   //len1为只读变量
{
    int arr1[len1] = {0};        //VS会报错
    const int len2 = 2;
    int arr2[len2] = {0};       //正确,len2是常量
}
//C++11中 const为只读，而常量则由constexpt来表示









//默认函数控制=delete 和 =default
//C++中的自定义类编译器会默认生成一些成员函数
//=delete表示禁用默认函数，=default表示启用默认函数

class Person
{
private:
    string m_name;
    int m_age;
    string m_sex;
public:
    Person(string name, int age， string sex):m_name(name), m_age(age), m_sex(sex){};    //定义有参构造函数
    Person()=default;   //定义了有参构造函数后，系统提供的无参构造函数会被禁用，若想继续使用，则需启用
    Person(const Person& p) = delete;   //删除拷贝构造函数
};
int main()
{
    Person p1("张三", 20, "男");   //有参构造
    Person p2;      //无参构造，若不启无参构造，则会报错
    Person p3(p1);  //报错
    return 0;
}





//初始化
//初始化时可以加= 也可以不加
int x={5};
int y{10};
int z = 11;     //都对

//创建对象时也可以用大括号来调用构造函数
class Person
{
public:
	int m_age;
	string m_name;
	Person(string name, int age) :m_name(name), m_age(age) {};
};
int main()
{
	Person p1{ "张三", 18 };

	return 0;
}

//STL容器提供了将initializer_list模板类作为参数的构造函数
vector<int> v1(10);     //把v1初始化为10个元素
vector<int> v2{10};     //把v2初始化为1个元素，该元素为10
vector<int> v3{3, 5, 8};    //把v3初始化为3个元素，值分别为3, 5, 8


//二维vector容器
vector<vector<int>> dp = vector<vecotr<int>>(n, vector<int>(m));    //定义一个nxm的二维数组
vector<vector<int>> dp = vector<vecotr<int>>(n, vector<int>(m, 0)); //定义一个nxm的二维数组，初始值为0
//或者遍历每行每列进行初始化
vector<vector<int>> dp(n, vector<int>(m, -1));      //也可以这样更简洁






//统一初始化列表initializer_list
//头文件#include<initializer_list>
#include<iostream>
#include<initializer_list>
using namespace std;
double sum(initializer_list<double> x)  //统一初始化列表为参数
{
	double total = 0;
	for (auto it = x.begin(); it != x.end(); it++)  
	{
		total += *it;
	}
	return total;
}
int main()
{
	//double total = sum(3.14, 5.20, 8);    //错误传参
	double total = sum({ 3.14, 5.20, 8 });  //正确传参
	cout << "total = "<< total <<"" << endl;    //total = 16.34

}









//memset函数(不需要头文件)
//主要用于初始化已分配的内存
//语法:  memset(void *ptr, int value, size_t num);
int arr[10];
memset(arr, 4, sizeof(arr));        //将arr的所有元素初始化为4


//memecpy函数(不需要头文件)
//用于在内存之间进行字节级别的数据拷贝。memcpy 可以将源内存区域的内容复制到目标内存区域，并返回指向目标内存区域的指针。//
//语法:   memcpy(void *dest, const void *src, size_t n);
        //dest为目标内存区域起始地址， src表示源内存区域起始地址，n表示复制的字节数
char src[] = "hello world";
char dest[20];
memcpy(dest, src, strlen(sre)+1);   //src被复制到了dest中，+1是为了包含'\0'





